<?
/*
* USAGE:
*
* $shoppingCart =& new ShoppingCart();
* $shoppingCart->retreive();
* $shoppingCart->addItem("itemCODE", 56.75, 4);  // Adds 4 items with code "itemCODE" and price 56,75.
* $shoppingCart->setItemQuantity("itemCODE", 6); // Updates item quantity.
* $shoppingCart->delItem("itemCODE");            // Delete Item from list.
* echo $shoppingCart->getTotalPrice();           // Prints total price
* print_r($shoppingCart->getItemsList());        // Get a list of object items stored.
*/

/*
 * @category   e-commerce
 * @package    ShoppingCart
 * @author     Alberto Pardo Saleme <apardo@adverit.com>
 * @copyright  2005 - AdVerit S.A. <www.adverit.com>
 * @version    Release: 1.0
 * @update     03/01/2006 03:09p.m.
 */


require_once(dirname(__FILE__) ."/Error.php");
require_once(dirname(__FILE__) ."/ShoppingCartItem.php");
require_once(dirname(__FILE__) ."/StorageBuilder.php");


class ShoppingCart extends Error
{
    // {{{ properties

    /**
     * The list with item objects
     * @var array
     */
    var $_items;

    /**
     * The shopping cart name or id
     * @var string
     */
    var $_name;

    /**
     * The ShoppingCartStorage refference that handles the items storage.
     * Types: cookie, mysql, file, etc...
     * @var ShoppingCartStorage
     */
    var $_storage;

    // }}}
    // {{{ constructor

    /**
     * This constructor sets up de storage object.
     *
     * @return void
     */
    function __construct($name = 'ShoppingCart', $storage = 'session')
    {
        $this->_items   = array();
        $this->_name    = $name;
        $storageBuilder = new StorageBuilder();
        $this->_storage = $storageBuilder->build($storage, $this->_name);
    }


    // }}}
    // {{{ addItem()

    /**
     * Adds an item object to cart
     *
     * @param id|string $id       The item's ID
     * @param int       $quantity The number of items contained
     * @param options   $options  An array of options. See ShoppingCartItem for further information.
     * @return void
     */
    function addItem($id, $quantity=1, $options=array())
    {
        if (array_key_exists($id, $this->_items))
            $this->_items[$id]->add($quantity);
        else
            $this->_items[$id] = new ShoppingCartItem($id, $quantity, $options);
    }

    // }}}
    // {{{ setItemQuantity()

    /**
     * Updates the number of the same items contained
     *
     * @param mixed  $id       The item's ID
     * @param int    $quantity The number of items contained
     * @return void
     */
    function setItemQuantity($id, $quantity)
    {
        if ($quantity==0) $this->delItem($id);
        else if (array_key_exists($id, $this->_items))
            $this->_items[$id]->setQuantity($quantity);
    }

    // }}}
    // {{{ deleteItem()

    /**
     * Removes an item from the cart
     *
     * @param mixed  $id  The item's ID
     * @return void
     */
    function deleteItem($id)
    {
        unset($this->_items[$id]);
    }

    // }}}
    // {{{ getItem()

    /**
     * Returns the object item from the given id.
     *
     * @param mixed  $id  The item's ID
     * @return ShoppingCartItem
     */
    function &getItem($id)
    {
        if (array_key_exists($id, $this->_items))
            return $this->_items[$id];
        else
            return null;
    }

    // }}}
    // {{{ getItemsList()

    /**
     * Returns the complete list of object items contained by the cart.
     *
     * @return array
     */
    function getItemsList()
    {
        $list = array();
        foreach($this->_items AS $item)
            array_push($list, $item);

        return $list;
    }

    // }}}
    // {{{ getTotalPrice()

    /**
     * Returns the complete list of object items contained by the cart.
     *
     * @param int    $round   Integer that defines the round aproximation
     * @param string $unit    The price unit inserted before the item's price
     *
     * @return array
     */
    function getTotalPrice($round=2, $unit="\$ ")
    {
        $total = 0;
        foreach($this->_items AS $item)
            $total += $item->getFinalPrice($round);

        return $unit . $total;
    }

    // }}}
    // {{{ getTotalQuantity()

    /**
     * Returns the number of items contained by the cart.
     *
     * @return int
     */
    function getTotalQuantity()
    {
        $total = 0;
        foreach($this->_items AS $item)
            $total += $item->quantity;

        return $total;
    }

    // }}}
    // {{{ store()

    /**
     * Stores items info
     *
     * @return void
     */
    function store()
    {
        if(is_object($this->_storage)) $this->_storage->store($this->_items);
    }

    // }}}
    // {{{ retreive()

    /**
     * Retreives stored data
     *
     * @return void
     */
    function retreive()
    {
        $this->_items = $this->_storage->retreive();
    }

    // }}}
    // {{{ destroy()

    /**
     * Destroys all cart data
     *
     * @return void
     */
    function destroy()
    {
        $this->_items   = array();
        $this->_name    = '';
        $this->_storage->destroy();
    }

    // }}}
    // {{{ destructor

    /**
     * This method is called when the ShoppingCart object has finished
     *
     * @return void
     */
    function __destruct()
    {
        $this->store();
    }

    // }}}
    // {{{ returns items serialized

    /**
     * This method is called when the ShoppingCart object has finished
     *
     * @return string
     */

    function serialize()
    {
        return serialize($this->_items);
    }

    // }}}
    // {{{ unserialize items and setup the shopping cart

    /**
     * This method is called when the ShoppingCart object has finished
     *
     * @return void
     */
    function unserialize($serialized)
    {
        $this->_items = unserialize($serialized);
    }

    // }}}
}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */

?>
